package service

import (
	"context"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
	"tFilm4/internal/model"
	"tFilm4/internal/service/internal/dao"
	"tFilm4/internal/service/internal/do"
)

type sMovieSession struct{}

var insMovieSession = sMovieSession{}

func MovieSession() *sMovieSession {
	return &insMovieSession
}
func (s *sMovieSession) CreateMovieSession(ctx context.Context, in model.CreateMovieSessionInput) (err error) {
	return dao.MovieSession.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
		insert, err := dao.SeatTable.Ctx(ctx).Data(do.SeatTable{
			Rows:       in.SeatTable.Rows,
			Cols:       in.SeatTable.Cols,
			Table:      in.SeatTable.Table,
			TotalCount: in.SeatTable.TotalCount,
			EmptyCount: in.SeatTable.EmptyCount,
		}).Insert()
		tableId, _ := insert.LastInsertId()
		_, err = dao.MovieSession.Ctx(ctx).Data(do.MovieSession{
			MovieId:      in.MovieId,
			MovieHallId:  in.HallId,
			StartTime:    in.StartTime,
			EndTime:      in.EndTime,
			SessionPrice: in.SessionPrice,
			SeatTableId:  tableId,
		}).Insert()
		return err
	})
}

func (s *sMovieSession) GetSessionList(ctx context.Context, in model.GetSessionInput) (count int, sessionInfos []model.SessionInfo, err error) {
	err = dao.MovieSession.Ctx(ctx).WhereLike("session_id", "%"+in.SearchKey+"%").WhereOrLike("session_id", "%"+in.SearchKey+"%").Page(in.PageNum, in.PageSize).ScanList(&sessionInfos, "MovieSession")
	if err != nil {
		return
	}
	err = dao.Movie.Ctx(ctx).Where("movie_id", gdb.ListItemValuesUnique(&sessionInfos, "MovieSession", "MovieId")).ScanList(&sessionInfos, "Movie", "MovieSession", "movie_id:MovieId")
	if err != nil {
		return
	}
	err = dao.MovieHall.Ctx(ctx).Where("hall_id", gdb.ListItemValuesUnique(&sessionInfos, "MovieSession", "MovieHallId")).ScanList(&sessionInfos, "MovieHall", "MovieSession", "hall_id:MovieHallId")
	if err != nil {
		return
	}
	err = dao.SeatTable.Ctx(ctx).Where("table_id", gdb.ListItemValuesUnique(&sessionInfos, "MovieSession", "SeatTableId")).ScanList(&sessionInfos, "SeatTable", "MovieSession", "table_id:SeatTableId")
	if err != nil {
		return
	}
	count, err = dao.MovieSession.Ctx(ctx).Count()
	return
}

func (s *sMovieSession) GetSessionListByHallTime(ctx context.Context, in model.GetSessionListByHallTimeInput) (count int, sessionInfos []model.SessionInfo, err error) {
	err = dao.MovieSession.Ctx(ctx).Where(g.Map{
		"movie_hall_id": in.HallId,
		"(start_time between ? and ? OR  end_time between ? and ?)": g.Slice{in.StartTime, in.EndTime, in.StartTime, in.EndTime},
	}).ScanList(&sessionInfos, "MovieSession")
	if err != nil {
		return
	}
	err = dao.Movie.Ctx(ctx).Where("movie_id", gdb.ListItemValuesUnique(&sessionInfos, "MovieSession", "MovieId")).ScanList(&sessionInfos, "Movie", "MovieSession", "movie_id:MovieId")
	if err != nil {
		return
	}
	err = dao.MovieHall.Ctx(ctx).Where("hall_id", gdb.ListItemValuesUnique(&sessionInfos, "MovieSession", "MovieHallId")).ScanList(&sessionInfos, "MovieHall", "MovieSession", "hall_id:MovieHallId")
	if err != nil {
		return
	}
	err = dao.SeatTable.Ctx(ctx).Where("table_id", gdb.ListItemValuesUnique(&sessionInfos, "MovieSession", "SeatTableId")).ScanList(&sessionInfos, "SeatTable", "MovieSession", "table_id:SeatTableId")
	if err != nil {
		return
	}
	count = len(sessionInfos)
	return
}

func (s *sMovieSession) GetSessionListByMovieTime(ctx context.Context, in model.GetSessionListByMovieTimeInput) (count int, sessionInfos []model.SessionInfo, err error) {
	err = dao.MovieSession.Ctx(ctx).Where(g.Map{
		"movie_id":                     in.MovieId,
		"(start_time between ? and ?)": g.Slice{in.StartTime, in.EndTime},
	}).ScanList(&sessionInfos, "MovieSession")
	if err != nil {
		return
	}
	err = dao.Movie.Ctx(ctx).Where("movie_id", gdb.ListItemValuesUnique(&sessionInfos, "MovieSession", "MovieId")).ScanList(&sessionInfos, "Movie", "MovieSession", "movie_id:MovieId")
	if err != nil {
		return
	}
	err = dao.MovieHall.Ctx(ctx).Where("hall_id", gdb.ListItemValuesUnique(&sessionInfos, "MovieSession", "MovieHallId")).ScanList(&sessionInfos, "MovieHall", "MovieSession", "hall_id:MovieHallId")
	if err != nil {
		return
	}
	err = dao.SeatTable.Ctx(ctx).Where("table_id", gdb.ListItemValuesUnique(&sessionInfos, "MovieSession", "SeatTableId")).ScanList(&sessionInfos, "SeatTable", "MovieSession", "table_id:SeatTableId")
	if err != nil {
		return
	}
	count = len(sessionInfos)
	return
}

func (s *sMovieSession) GetSessionById(ctx context.Context, sessionId int64) (info model.SessionInfo, err error) {
	var sessionInfos []model.SessionInfo
	err = dao.MovieSession.Ctx(ctx).Where(g.Map{
		"session_id":                     sessionId,
	}).ScanList(&sessionInfos, "MovieSession")
	if err != nil {
		return
	}
	err = dao.Movie.Ctx(ctx).Where("movie_id", gdb.ListItemValuesUnique(&sessionInfos, "MovieSession", "MovieId")).ScanList(&sessionInfos, "Movie", "MovieSession", "movie_id:MovieId")
	if err != nil {
		return
	}
	err = dao.MovieHall.Ctx(ctx).Where("hall_id", gdb.ListItemValuesUnique(&sessionInfos, "MovieSession", "MovieHallId")).ScanList(&sessionInfos, "MovieHall", "MovieSession", "hall_id:MovieHallId")
	if err != nil {
		return
	}
	err = dao.SeatTable.Ctx(ctx).Where("table_id", gdb.ListItemValuesUnique(&sessionInfos, "MovieSession", "SeatTableId")).ScanList(&sessionInfos, "SeatTable", "MovieSession", "table_id:SeatTableId")
	if err != nil {
		return
	}
	info=sessionInfos[0]
	return
}